package internal

import (
	"fmt"
	"runtime"
)

// CustomError 自定义错误类型
type CustomError struct {
	Code    string
	Message string
	Cause   error
}

func (e *CustomError) Error() string {
	if e.Cause != nil {
		return fmt.Sprintf("%s: %s (caused by: %v)", e.Code, e.Message, e.Cause)
	}
	return fmt.Sprintf("%s: %s", e.Code, e.Message)
}

func (e *CustomError) Unwrap() error {
	return e.Cause
}

// Error codes
const (
	ErrCodeConfig      = "CONFIG_ERROR"
	ErrCodeDatabase    = "DATABASE_ERROR"
	ErrCodeSSH         = "SSH_ERROR"
	ErrCodeSync        = "SYNC_ERROR"
	ErrCodeValidation  = "VALIDATION_ERROR"
	ErrCodeFile        = "FILE_ERROR"
)

// NewError 创建新的自定义错误
func NewError(code, message string, cause error) *CustomError {
	return &CustomError{
		Code:    code,
		Message: message,
		Cause:   cause,
	}
}

// NewConfigError 创建配置错误
func NewConfigError(message string, cause error) *CustomError {
	return NewError(ErrCodeConfig, message, cause)
}

// NewDatabaseError 创建数据库错误
func NewDatabaseError(message string, cause error) *CustomError {
	return NewError(ErrCodeDatabase, message, cause)
}

// NewSSHError 创建SSH错误
func NewSSHError(message string, cause error) *CustomError {
	return NewError(ErrCodeSSH, message, cause)
}

// NewSyncError 创建同步错误
func NewSyncError(message string, cause error) *CustomError {
	return NewError(ErrCodeSync, message, cause)
}

// NewValidationError 创建验证错误
func NewValidationError(message string, cause error) *CustomError {
	return NewError(ErrCodeValidation, message, cause)
}

// NewFileError 创建文件错误
func NewFileError(message string, cause error) *CustomError {
	return NewError(ErrCodeFile, message, cause)
}

// SafeRecover 安全的panic恢复
func SafeRecover() {
	if r := recover(); r != nil {
		// 获取调用栈
		buf := make([]byte, 4096)
		n := runtime.Stack(buf, false)
		Error("Panic recovered: %v\nStack trace:\n%s", r, string(buf[:n]))
	}
}

// ValidateNotEmpty 验证字符串不为空
func ValidateNotEmpty(value, fieldName string) error {
	if value == "" {
		return NewValidationError(fmt.Sprintf("%s cannot be empty", fieldName), nil)
	}
	return nil
}

// ValidateNotNil 验证指针不为nil
func ValidateNotNil(value interface{}, fieldName string) error {
	if value == nil {
		return NewValidationError(fmt.Sprintf("%s cannot be nil", fieldName), nil)
	}
	return nil
}
